package fr.bull.learn.thread.task;

import org.apache.log4j.Logger;

import fr.bull.learn.thread.util.Chrono;

/**
 * Fibotask compute
 * @author Rouviere-X
 *
 */
public abstract class FiboTask<N> implements Runnable {
	private Logger log = Logger.getLogger(getClass());
	private int call;

	private N res;
	
	/**
	 * owerflow
	 * @param a
	 * @param b
	 * @return
	 */
	private N fibo(N a, N b) {
		call++;
		res = add(a, b);
		return fibo(b, res);
	}
	
	/**
	 * Add a and b
	 * @param a
	 * @param b
	 * @return a + b
	 */
	protected abstract N add(N a, N b);
	
	/**
	 * Get zero value for N
	 * @return
	 */
	protected abstract N getZero();
	
	/**
	 * Get one value for N
	 * @return
	 */
	protected abstract N getOne();
	
	@Override
	public void run() {
		Chrono c = new Chrono();
		c.start();
		try {
			fibo(getZero(),getOne());
		}catch (StackOverflowError e) {
			c.stop();
			log.info("res=["+res+"]");
			log.error("too many call "+call);
			log.info(" time "+c.toString());
		}
		
	}

}
